package controllers

import (
	"backend/common"
	"backend/models"
	"fmt"
	"math/rand"
	"net/http"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

// CheckUserExistence 检查用户是否存在
func CheckUserExistence(ctx *gin.Context) {
	db := common.GetDB()
	email := strings.Trim(ctx.Query("email"), "\"")

	var user models.User
	db.Where("email = ?", email).First(&user)

	if user.ID <= 0 {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "用户不存在",
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "用户存在",
	})
}

// GetVerificationCode 生成6位数字验证码
func GetVerificationCode() string {
	rand.Seed(time.Now().UnixNano())
	code := make([]byte, 6)
	for i := range code {
		code[i] = byte(rand.Intn(10)) + '0'
	}
	return string(code)
}

// SendVerificationEmail 发送验证码邮件
func SendVerificationEmail(email, code string) error {
	mail := common.Mail{
		From:    "buildmind@126.com",
		To:      []string{email},
		Subject: "您的验证码",
		Body:    fmt.Sprintf("您的验证码是：%s，有效期为5分钟。", code),
	}
	return common.SendMail(mail)
}

// GetRegisterCode 获取注册验证码
func GetRegisterCode(ctx *gin.Context) {
	db := common.GetDB()
	email := strings.Trim(ctx.Query("email"), "\"")
	code := GetVerificationCode()

	var user models.User
	db.Where("email = ?", email).First(&user)

	if user.ID > 0 {
		if user.PasswordHash != "" {
			ctx.JSON(http.StatusUnprocessableEntity, gin.H{
				"status":  "error",
				"message": "用户已存在",
			})
			return
		}
		db.Model(&user).Update("verification_code", code)
	} else {
		db.Create(&models.User{
			Email:            email,
			VerificationCode: code,
		})
	}

	if err := SendVerificationEmail(email, code); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"status":  "error",
			"message": "验证码发送失败",
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "验证码已发送",
	})
}

// Register 用户注册
func Register(ctx *gin.Context) {
	db := common.GetDB()
	var requestUser models.User
	ctx.Bind(&requestUser)

	var user models.User
	db.Where("email = ?", requestUser.Email).First(&user)

	if user.ID <= 0 {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "账号错误",
		})
		return
	}

	if user.PasswordHash != "" {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "用户已存在",
		})
		return
	}

	if requestUser.VerificationCode != user.VerificationCode {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "验证码错误",
		})
		return
	}

	if requestUser.PasswordHash == "" {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "密码不可为空",
		})
		return
	}

	db.Model(&user).Update("password_hash", requestUser.PasswordHash)
	setCookie(ctx, requestUser.Email)

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "注册成功",
	})
}

// GetLoginAndResetCode 获取登录/重置密码验证码
func GetLoginAndResetCode(ctx *gin.Context) {
	db := common.GetDB()
	email := strings.Trim(ctx.Query("email"), "\"")
	code := GetVerificationCode()

	var user models.User
	db.Where("email = ?", email).First(&user)

	if user.ID <= 0 || user.PasswordHash == "" {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "用户不存在",
		})
		return
	}

	db.Model(&user).Update("verification_code", code)

	if err := SendVerificationEmail(email, code); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"status":  "error",
			"message": "验证码发送失败",
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "验证码已发送",
	})
}

// EmailLogin 邮箱验证码登录
func EmailLogin(ctx *gin.Context) {
	db := common.GetDB()
	var requestUser models.User
	ctx.Bind(&requestUser)

	var user models.User
	db.Where("email = ?", requestUser.Email).First(&user)

	if user.ID <= 0 || user.PasswordHash == "" {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "用户不存在",
		})
		return
	}

	if requestUser.VerificationCode != user.VerificationCode {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "验证码错误",
		})
		return
	}

	setCookie(ctx, requestUser.Email)

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "登录成功",
	})
}

// PasswordLogin 密码登录
func PasswordLogin(ctx *gin.Context) {
	db := common.GetDB()
	var requestUser models.User
	ctx.Bind(&requestUser)

	var user models.User
	db.Where("email = ?", requestUser.Email).First(&user)

	if user.ID <= 0 {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "用户不存在",
		})
		return
	}

	if requestUser.PasswordHash != user.PasswordHash {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "密码错误",
		})
		return
	}

	setCookie(ctx, requestUser.Email)

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "登录成功",
	})
}

// ResetPassword 重置密码
func ResetPassword(ctx *gin.Context) {
	db := common.GetDB()
	var requestUser models.User
	ctx.Bind(&requestUser)

	var user models.User
	db.Where("email = ?", requestUser.Email).First(&user)

	if user.ID <= 0 || user.PasswordHash == "" {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "用户不存在",
		})
		return
	}

	if requestUser.VerificationCode != user.VerificationCode {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "验证码错误",
		})
		return
	}

	if requestUser.PasswordHash == "" {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "密码不可为空",
		})
		return
	}

	db.Model(&user).Update("password_hash", requestUser.PasswordHash)
	setCookie(ctx, requestUser.Email)

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "密码重置成功",
	})
}

// CheckCookieExistence 检查Cookie是否存在
func CheckCookieExistence(ctx *gin.Context) {
	id, err := ctx.Cookie("userid")
	if err != nil || id == "" {
		ctx.JSON(http.StatusUnauthorized, gin.H{
			"status":  "error",
			"message": "用户未登录",
		})
		return
	}

	token, err := ctx.Cookie("usertoken")
	if err != nil || token == "" {
		ctx.JSON(http.StatusUnauthorized, gin.H{
			"status":  "error",
			"message": "用户未登录",
		})
		return
	}

	if checkCookie(id, token) {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  "success",
			"message": "用户已登录",
		})
		return
	}

	ctx.JSON(http.StatusNotFound, gin.H{
		"status":  "error",
		"message": "用户信息错误",
	})
}

// Logout 用户登出
func Logout(ctx *gin.Context) {
	removeCookie(ctx)
	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "登出成功",
	})
}

// SetName 设置用户名
func SetName(ctx *gin.Context) {
	email, _ := ctx.Cookie("userid")
	var requestUser models.User
	ctx.Bind(&requestUser)

	db := common.GetDB()
	var user models.User
	db.Where("email = ?", email).First(&user)
	db.Model(&user).Update("name", requestUser.Name)

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "用户名设置成功",
	})
}

// GetUser 获取用户信息
func GetUser(ctx *gin.Context) {
	email, _ := ctx.Cookie("userid")

	db := common.GetDB()
	var user models.User
	db.Where("email = ?", email).First(&user)

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "查询成功",
		"data": gin.H{
			"id":    user.ID,
			"email": user.Email,
			"name":  user.Name,
		},
	})
}
